from typing import List, Dict, Any, Optional
from enum import Enum
from dataclasses import dataclass
from .data_manager import DataManager, ChangeType


class OperationType(Enum):
    """操作类型"""
    INSERT_ROW = "insert_row"
    DELETE_ROW = "delete_row"
    UPDATE_CELL = "update_cell"
    UPDATE_ROW_STATUS = "update_row_status"  # 行状态更新（禁用/启用）
    ADD_COLUMN = "add_column"
    INSERT_COLUMN = "insert_column"  # 插入列
    REMOVE_COLUMN = "remove_column"
    REORDER_COLUMNS = "reorder_columns"
    MARK_COLUMNS = "mark_columns"


@dataclass
class UndoOperation:
    """撤销操作"""
    operation_type: OperationType
    data: Dict[str, Any]
    description: str


class UndoManager:
    """撤销管理器 - 与数据管理器集成"""
    
    def __init__(self, data_manager: DataManager):
        self._data_manager = data_manager
        self._undo_stack: List[UndoOperation] = []
        self._redo_stack: List[UndoOperation] = []
        self._max_stack_size = 100
        
    def can_undo(self) -> bool:
        """是否可以撤销"""
        return len(self._undo_stack) > 0
    
    def can_redo(self) -> bool:
        """是否可以重做"""
        return len(self._redo_stack) > 0
    
    def undo(self) -> bool:
        """撤销操作"""
        if not self.can_undo():
            return False
            
        operation = self._undo_stack.pop()
        
        try:
            if operation.operation_type == OperationType.INSERT_ROW:
                # 撤销添加行/插入行 - 删除行
                row_index = operation.data['row_index']
                self._data_manager.remove_row(row_index)
                
            elif operation.operation_type == OperationType.DELETE_ROW:
                # 撤销删除行 - 添加行
                row_data = operation.data['row_data']
                row_index = operation.data['row_index']
                # 使用insert_row方法在原来的位置插入行
                self._data_manager.insert_row(row_index, row_data)
                
            elif operation.operation_type == OperationType.UPDATE_CELL:
                # 撤销单元格更新
                row = operation.data['row']
                col = operation.data['col']
                old_value = operation.data['old_value']
                # 直接修改数据而不触发事件，避免无限循环
                self._data_manager._data[row][col] = old_value
                self._data_manager._modified_cells.add((row, col))
                
            elif operation.operation_type == OperationType.ADD_COLUMN:
                # 撤销添加列 - 删除列
                # 使用当前列数减1作为要删除的列索引，因为添加的列总是在末尾
                col_count = self._data_manager.get_column_count()
                if col_count > 0:
                    self._data_manager.remove_column(col_count - 1)
                
            elif operation.operation_type == OperationType.INSERT_COLUMN:
                # 撤销插入列 - 删除列
                col_index = operation.data['col_index']
                self._data_manager.remove_column(col_index)
                
            elif operation.operation_type == OperationType.REMOVE_COLUMN:
                # 撤销删除列 - 添加列
                header = operation.data['header']
                col_index = operation.data['col_index']
                # 使用insert_column方法在原来的位置插入列
                self._data_manager.insert_column(col_index, header)
                
            elif operation.operation_type == OperationType.REORDER_COLUMNS:
                # 撤销列重排序
                old_order = operation.data['old_order']
                self._data_manager.set_column_order(old_order)
                
            elif operation.operation_type == OperationType.MARK_COLUMNS:
                # 撤销列标记
                old_marked = operation.data['old_marked']
                self._data_manager.set_marked_columns(old_marked)
                
            elif operation.operation_type == OperationType.UPDATE_ROW_STATUS:
                # 撤销行状态更新（禁用/启用）
                row_indices = operation.data['row_indices']
                action = operation.data['action']
                
                if action == 'disable':
                    # 撤销禁用操作 - 启用行
                    for row in row_indices:
                        self._data_manager.enable_row(row)
                elif action == 'enable':
                    # 撤销启用操作 - 禁用行
                    for row in row_indices:
                        self._data_manager.disable_row(row)
            
            # 将操作添加到重做栈
            self._redo_stack.append(operation)
            
            # 限制栈大小
            if len(self._redo_stack) > self._max_stack_size:
                self._redo_stack.pop(0)
                
            return True
            
        except Exception as e:
            print(f"撤销操作失败: {e}")
            # 操作失败时，将操作放回撤销栈
            self._undo_stack.append(operation)
            return False
    
    def redo(self) -> bool:
        """重做操作"""
        if not self.can_redo():
            return False
            
        operation = self._redo_stack.pop()
        
        try:
            if operation.operation_type == OperationType.INSERT_ROW:
                # 重做插入行 - 在原来的位置插入
                row_data = operation.data['row_data']
                row_index = operation.data['row_index']
                self._data_manager.insert_row(row_index, row_data)
                
            elif operation.operation_type == OperationType.DELETE_ROW:
                # 重做删除行
                row_index = operation.data['row_index']
                self._data_manager.remove_row(row_index)
                
            elif operation.operation_type == OperationType.UPDATE_CELL:
                # 重做单元格更新
                row = operation.data['row']
                col = operation.data['col']
                new_value = operation.data['new_value']
                # 直接修改数据而不触发事件，避免无限循环
                self._data_manager._data[row][col] = new_value
                self._data_manager._modified_cells.add((row, col))
                
            elif operation.operation_type == OperationType.ADD_COLUMN:
                # 重做添加列
                header = operation.data['header']
                self._data_manager.add_column(header)
                
            elif operation.operation_type == OperationType.INSERT_COLUMN:
                # 重做插入列
                position = operation.data['position']
                header = operation.data['header']
                default_value = operation.data.get('default_value', '')
                self._data_manager.insert_column(position, header, default_value)
                
            elif operation.operation_type == OperationType.REMOVE_COLUMN:
                # 重做删除列
                col_index = operation.data['col_index']
                self._data_manager.remove_column(col_index)
                
            elif operation.operation_type == OperationType.REORDER_COLUMNS:
                # 重做列重排序
                new_order = operation.data['new_order']
                self._data_manager.set_column_order(new_order)
                
            elif operation.operation_type == OperationType.MARK_COLUMNS:
                # 重做列标记
                new_marked = operation.data['new_marked']
                self._data_manager.set_marked_columns(new_marked)
                
            elif operation.operation_type == OperationType.UPDATE_ROW_STATUS:
                # 重做行状态更新（禁用/启用）
                row_indices = operation.data['row_indices']
                action = operation.data['action']
                
                if action == 'disable':
                    # 重做禁用操作
                    for row in row_indices:
                        self._data_manager.disable_row(row)
                elif action == 'enable':
                    # 重做启用操作
                    for row in row_indices:
                        self._data_manager.enable_row(row)
            
            # 将操作添加到撤销栈
            self._undo_stack.append(operation)
            
            # 限制栈大小
            if len(self._undo_stack) > self._max_stack_size:
                self._undo_stack.pop(0)
                
            return True
            
        except Exception as e:
            print(f"重做操作失败: {e}")
            # 操作失败时，将操作放回重做栈
            self._redo_stack.append(operation)
            return False

    def add_operation(self, operation_type: OperationType, data: Dict[str, Any], description: str):
        """添加操作到撤销栈"""
        operation = UndoOperation(operation_type, data, description)
        self._undo_stack.append(operation)
        
        # 清空重做栈
        self._redo_stack.clear()
        
        # 限制栈大小
        if len(self._undo_stack) > self._max_stack_size:
            self._undo_stack.pop(0)
    
    def clear(self):
        """清空撤销/重做栈"""
        self._undo_stack.clear()
        self._redo_stack.clear()
    
    def get_undo_description(self) -> Optional[str]:
        """获取下一个撤销操作的描述"""
        if self.can_undo():
            return self._undo_stack[-1].description
        return None
    
    def get_redo_description(self) -> Optional[str]:
        """获取下一个重做操作的描述"""
        if self.can_redo():
            return self._redo_stack[-1].description
        return None
